package com.ruoyix.aicode.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyix.aicode.domain.*;
import com.ruoyix.aicode.util.CodeGenerationUtil;
import com.ruoyix.aicode.util.HtmlGenerationUtil;
import com.ruoyix.aicode.util.LlmUtil;
import com.ruoyix.aicode.util.VueGenerationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.FluxSink;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 前端代码生成服务
 */
@Service
public class FrontCodeService {
    private static final Logger logger = LoggerFactory.getLogger(FrontCodeService.class);
    private final ObjectMapper objectMapper = new ObjectMapper();

    // 存储每个阶段的累积内容
    private final Map<String, StringBuilder> stageContentMap = new ConcurrentHashMap<>();

    // 存储骨架代码
    private StringBuilder skeletonCode = new StringBuilder();

    // 存储页面结构数组
    private final List<PageSection> pageSections = new ArrayList<>();

    // 存储已生成的组件代码
    private final Map<String, String> generatedComponents = new ConcurrentHashMap<>();

    // 事件发送器
    private FluxSink<String> eventSink;

    // 页面风格设定
    private PageStyle pageStyle = new PageStyle();

    // 存储全局对话上下文历史
    private final List<Message> conversationHistory = new ArrayList<>();

    // 全局上下文开关
    private boolean useGlobalContext = true;

    /**
     * 处理代码生成请求
     *
     * @param request 请求对象
     * @return 事件流
     */
    public Flux<String> generateCode(CodeGenerationRequest request) {
        // 清空之前的状态
        stageContentMap.clear();
        skeletonCode = new StringBuilder();
        generatedComponents.clear();
        pageSections.clear();
        conversationHistory.clear();

        // 设置全局上下文开关
        this.useGlobalContext = request.isUseGlobalContext();
        logger.info("全局上下文开关状态: {}", this.useGlobalContext);

        // 处理页面风格设置
        if (request.getPageStyle() != null) {
            updatePageStyle(request.getPageStyle());
            // 手动获取描述字段值
            String description = "";
            try {
                // 使用toString()查看是否包含description信息
                String styleStr = pageStyle.toString();
                if (styleStr.contains("description=")) {
                    description = styleStr.substring(styleStr.indexOf("description=") + "description=".length());
                    if (description.contains(",")) {
                        description = description.substring(0, description.indexOf(","));
                    }
                }
            } catch (Exception e) {
                description = "已更新";
            }
            logger.info("页面风格已更新: {}", description);
        }

        // 获取代码类型（html或vue）
        String codeType = request.getCodeType() != null ? request.getCodeType().toLowerCase() : "html";
        logger.info("代码生成类型: {}", codeType);

        // 添加初始系统提示
        conversationHistory.add(new Message("system", "你是一个专业的前端开发助手，可以分析需求并生成前端代码。"));

        // 创建一个Flux，可以通过eventSink发送事件
        return Flux.create(sink -> {
            this.eventSink = sink;

            // 测试消息
            String testMessage = "{\"test\":\"这是一条测试消息，确认流是否正常工作\"}";
            logger.info("发送测试消息到前端: {}", testMessage);
            sink.next(testMessage);

            // 启动代码生成流程 - 根据代码类型选择不同的生成路径
            if ("vue".equalsIgnoreCase(codeType)) {
                generateVueCodeInSteps(request.getRequirements())
                    .subscribe(
                        data -> {
                            if (!data.isEmpty()) {
                                sink.next(data);
                            }
                        },
                        error -> {
                            logger.error("Vue代码生成出错: {}", error.getMessage(), error);
                            sink.error(error);
                        },
                        () -> {
                            logger.info("Vue代码生成完成");
                            sink.complete();
                        }
                    );
            } else {
                // 默认HTML生成路径 - 使用原有的方法
                generateCodeInSteps(request.getRequirements())
                    .subscribe(
                        data -> {
                            if (!data.isEmpty()) {
                                sink.next(data);
                            }
                        },
                        error -> {
                            logger.error("代码生成出错: {}", error.getMessage(), error);
                            sink.error(error);
                        },
                        () -> {
                            logger.info("代码生成完成");
                            sink.complete();
                        }
                    );
            }
        });
    }

    /**
     * 分步骤生成代码
     *
     * @param requirements 需求
     * @return 事件流
     */
    private Flux<String> generateCodeInSteps(String requirements) {
        logger.info("开始生成代码步骤，需求长度: {}", requirements.length());

        // 使用纯响应式方式处理流
        return Flux.create(sink -> {
            this.eventSink = sink;  // 保存全局引用，以便其他方法可以使用

            try {
                // 步骤0: 风格设定
                logger.info("开始执行步骤0: 页面风格设定");

                // 发送步骤开始事件
                String styleStartEvent = "{\"stage\": \"style\", \"status\": \"start\", \"message\": \"开始设定页面风格\"}";
                logger.info("发送风格设定开始事件: {}", styleStartEvent);
                sink.next(styleStartEvent);

                // 使用当前的页面风格设置
                String styleCompleteEvent = createStepCompleteEvent("style_complete", "页面风格设定完成", "style");
                Map<String, Object> styleJsonObject = objectMapper.readValue(styleCompleteEvent, Map.class);
                styleJsonObject.put("styleInfo", pageStyle);
                String styleJsonStr = objectMapper.writeValueAsString(styleJsonObject);
                logger.info("发送风格设定完成事件: {}", styleJsonStr);
                sink.next(styleJsonStr);

                // 步骤1: 分析需求及页面结构
                logger.info("开始执行步骤1: 分析需求及页面结构");

                // 发送步骤开始事件
                String analysisStartEvent = "{\"stage\": \"analysis\", \"status\": \"start\", \"message\": \"开始分析需求\"}";
                logger.info("发送分析开始事件: {}", analysisStartEvent);
                sink.next(analysisStartEvent);

                // 调用LLM分析需求 - 使用非阻塞方式
                String prompt = CodeGenerationUtil.buildAnalysisPrompt(requirements);
                String systemPrompt = "现在你正在执行分析阶段，请作为一个专业的前端开发分析师，分析用户需求并设计页面结构。请使用<!-- SECTION>标签格式返回页面结构。";

                List<Map<String, String>> messages = LlmUtil.prepareMessages(
                    conversationHistory, useGlobalContext, systemPrompt, prompt);

                LlmUtil.callLLM(messages, chunk -> {
                    // 将响应保存到阶段内容中
                    if (!stageContentMap.containsKey("analysis")) {
                        stageContentMap.put("analysis", new StringBuilder());
                    }
                    stageContentMap.get("analysis").append(chunk);

                    // 发送进度事件
                    try {
                        String eventData = String.format("{\"stage\": \"%s\", \"status\": \"progress\", \"content\": %s}",
                            "analysis", objectMapper.writeValueAsString(chunk));
                        sink.next(eventData);
                    } catch (Exception e) {
                        logger.error("发送进度事件出错: {}", e.getMessage(), e);
                    }
                })
                .doOnSuccess(v -> {
                    try {
                        logger.info("分析需求完成，解析页面结构");
                        if (stageContentMap.containsKey("analysis")) {
                            String analysisContent = stageContentMap.get("analysis").toString();
                            CodeGenerationUtil.parsePageStructure(analysisContent, pageSections);

                            // 保存助手响应到历史
                            if (useGlobalContext) {
                                conversationHistory.add(new Message("assistant", analysisContent));
                            }
                        } else {
                            logger.error("未找到analysis阶段的内容");
                        }

                        List<String> ids = pageSections.stream()
                            .map(PageSection::getId)
                            .collect(Collectors.toList());

                        // 发送步骤完成事件
                        String analysisCompleteEvent = createStepCompleteEvent("analysis_complete", "需求分析完成", "analysis");
                        Map<String, Object> analysisJsonObject = objectMapper.readValue(analysisCompleteEvent, Map.class);
                        analysisJsonObject.put("steps", ids);
                        String analysisJsonStr = objectMapper.writeValueAsString(analysisJsonObject);
                        logger.info("发送分析完成事件: {}", analysisJsonStr);
                        sink.next(analysisJsonStr);

                        // 步骤2: 生成页面骨架
                        startSkeletonGeneration(requirements, sink);
                    } catch (Exception e) {
                        logger.error("处理分析结果时出错: {}", e.getMessage(), e);
                        sink.error(e);
                    }
                })
                .subscribe(
                    null,
                    error -> {
                        logger.error("分析需求过程中出错: {}", error.getMessage(), error);
                        sink.error(error);
                    }
                );
            } catch (Exception e) {
                logger.error("启动生成流程时出错: {}", e.getMessage(), e);
                sink.error(e);
            }
        });
    }

    /**
     * 启动骨架生成步骤
     *
     * @param requirements 需求
     * @param sink 事件接收器
     */
    private void startSkeletonGeneration(String requirements, FluxSink<String> sink) {
        logger.info("步骤1完成，开始执行步骤2: 生成页面骨架");

        // 发送步骤开始事件 - 移除data:前缀和\n\n后缀
        String skeletonStartEvent = "{\"stage\": \"skeleton\", \"status\": \"start\", \"message\": \"开始生成页面骨架\"}";
        logger.info("发送骨架开始事件: {}", skeletonStartEvent);
        sink.next(skeletonStartEvent);

        try {
            // 直接使用模板生成骨架代码，而不是调用LLM
            String generatedSkeleton = HtmlGenerationUtil.generateSkeletonFromTemplate(
                requirements, pageSections, pageStyle,
                stageContentMap.containsKey("analysis") ? stageContentMap.get("analysis") : null);

            // 保存骨架代码
            skeletonCode = new StringBuilder(generatedSkeleton);
            logger.info("页面骨架生成完成，骨架代码长度: {}", skeletonCode.length());

            // 将骨架代码保存到阶段内容中
            stageContentMap.put("skeleton", skeletonCode);

            // 发送步骤完成事件
            String skeletonCompleteEvent = createStepCompleteEvent("skeleton_complete", "页面骨架生成完成", "skeleton");
            logger.info("发送骨架完成事件: {}", skeletonCompleteEvent);
            sink.next(skeletonCompleteEvent);

            // 步骤3: 生成组件
            startComponentsGeneration(requirements, sink);
        } catch (Exception e) {
            logger.error("生成骨架时出错: {}", e.getMessage(), e);
            sink.error(e);
        }
    }

    /**
     * 启动组件生成步骤
     *
     * @param requirements 需求
     * @param sink 事件接收器
     */
    private void startComponentsGeneration(String requirements, FluxSink<String> sink) {
        logger.info("步骤2完成，开始执行步骤3: 生成组件");

        // 发送步骤开始事件 - 移除data:前缀和\n\n后缀
        String componentsStartEvent = "{\"stage\": \"components\", \"status\": \"start\", \"message\": \"开始生成组件\"}";
        logger.info("发送组件开始事件: {}", componentsStartEvent);
        sink.next(componentsStartEvent);

        if (!pageSections.isEmpty()) {
            // 如果解析出了页面结构，按层级生成组件
            generateComponentsHierarchically(requirements, sink)
                .doOnSuccess(v -> {
                    finishGeneration(sink);
                })
                .subscribe(
                    null,
                    error -> {
                        logger.error("生成组件过程中出错: {}", error.getMessage(), error);
                        sink.error(error);
                    }
                );
        } else {
            // 如果没有解析出结构，使用兜底方案
            String prompt = CodeGenerationUtil.buildGenericComponentsPrompt(requirements);
            String systemPrompt = "现在你正在生成组件，请作为一个专业的前端开发者，创建完整的页面组件。每个组件应包括HTML结构、CSS样式和必要的JavaScript功能。";

            List<Map<String, String>> messages = LlmUtil.prepareMessages(
                conversationHistory, useGlobalContext, systemPrompt, prompt);

            LlmUtil.callLLM(messages, chunk -> {
                // 将响应保存到阶段内容中
                if (!stageContentMap.containsKey("components")) {
                    stageContentMap.put("components", new StringBuilder());
                }
                stageContentMap.get("components").append(chunk);

                // 发送进度事件
                try {
                    String eventData = String.format("{\"stage\": \"%s\", \"status\": \"progress\", \"content\": %s}",
                        "components", objectMapper.writeValueAsString(chunk));
                    sink.next(eventData);
                } catch (Exception e) {
                    logger.error("发送进度事件出错: {}", e.getMessage(), e);
                }
            })
            .doOnSuccess(v -> {
                try {
                    // 保存助手响应到历史
                    if (useGlobalContext && stageContentMap.containsKey("components")) {
                        conversationHistory.add(new Message("assistant", stageContentMap.get("components").toString()));
                    }

                    // 发送步骤完成事件
//                    String componentsCompleteEvent = createStepCompleteEvent("components_complete", "组件生成完成", "components");
//                    logger.info("发送组件完成事件: {}", componentsCompleteEvent);
//                    sink.next(componentsCompleteEvent);

                    // 完成生成流程
                    finishGeneration(sink);
                } catch (Exception e) {
                    logger.error("处理组件生成结果时出错: {}", e.getMessage(), e);
                    sink.error(e);
                }
            })
            .subscribe(
                null,
                error -> {
                    logger.error("生成通用组件过程中出错: {}", error.getMessage(), error);
                    sink.error(error);
                }
            );
        }
    }

    /**
     * 按层级生成组件
     *
     * @param requirements 需求
     * @param sink 事件接收器
     * @return 完成信号
     */
    private Mono<Void> generateComponentsHierarchically(String requirements, FluxSink<String> sink) {
        logger.info("开始按层级生成组件");

        // 按层级生成组件
        return generateComponentsByLevel(requirements, pageSections, 0, sink)
            .doOnSuccess(v -> {
                // 所有组件生成完毕，发送组件完成事件
                String componentsCompleteEvent = createStepCompleteEvent("components_complete", "组件生成完成", "components");
                logger.info("发送组件完成事件: {}", componentsCompleteEvent);
                sink.next(componentsCompleteEvent);

                // 打印最终完整代码
                logger.info("所有组件生成完毕，最终完整代码：\n{}", skeletonCode.toString());
            });
    }

    /**
     * 按层级递归生成组件
     *
     * @param requirements 需求
     * @param sections 页面部分列表
     * @param level 层级
     * @param sink 事件接收器
     * @return 完成信号
     */
    private Mono<Void> generateComponentsByLevel(String requirements, List<PageSection> sections, int level, FluxSink<String> sink) {
        // 根据当前级别过滤出要处理的节点
        List<PageSection> currentLevelSections = new ArrayList<>();
        Map<String, List<PageSection>> nextLevelChildrenMap = new HashMap<>();

        // 收集本层级的所有节点及其子节点
        collectLevelSections(sections, level, 0, currentLevelSections, nextLevelChildrenMap);

        if (currentLevelSections.isEmpty()) {
            logger.info("层级 {} 没有组件，生成完成", level);
            return Mono.empty();
        }

        logger.info("开始生成第 {} 层，共 {} 个组件", level+1, currentLevelSections.size());

        // 顺序处理当前层级的所有节点 - 使用严格顺序执行，确保一个组件完全生成后再生成下一个
        return processLevelSectionsSequentially(requirements, currentLevelSections, 0, sink)
            .then(Mono.defer(() -> {
                // 当前层级全部处理完毕后，处理下一层级
                if (!nextLevelChildrenMap.isEmpty()) {
                    // 提取下一级所有的子节点列表
                    List<PageSection> allNextLevelSections = new ArrayList<>();
                    nextLevelChildrenMap.values().forEach(allNextLevelSections::addAll);

                    logger.info("第 {} 层组件生成完毕，开始生成第 {} 层", level+1, level+2);
                    return generateComponentsByLevel(requirements, allNextLevelSections, 0, sink);
                }
                return Mono.empty();
            }));
    }

    /**
     * 收集指定层级的节点
     *
     * @param sections 页面部分列表
     * @param targetLevel 目标层级
     * @param currentLevel 当前层级
     * @param result 结果列表
     * @param childrenMap 子节点映射
     */
    private void collectLevelSections(List<PageSection> sections, int targetLevel, int currentLevel,
                                     List<PageSection> result, Map<String, List<PageSection>> childrenMap) {
        if (currentLevel == targetLevel) {
            // 当前级别是目标级别，添加到结果中
            result.addAll(sections);

            // 收集子节点用于下一级处理
            for (PageSection section : sections) {
                if (!section.getChildren().isEmpty()) {
                    childrenMap.put(section.getId(), section.getChildren());
                }
            }
        } else if (currentLevel < targetLevel) {
            // 继续向下查找
            for (PageSection section : sections) {
                collectLevelSections(section.getChildren(), targetLevel, currentLevel + 1, result, childrenMap);
            }
        }
    }

    /**
     * 严格顺序处理当前层级的节点，确保前一个组件完全生成后再生成下一个
     *
     * @param requirements 需求
     * @param sections 页面部分列表
     * @param index 当前索引
     * @param sink 事件接收器
     * @return 完成信号
     */
    private Mono<Void> processLevelSectionsSequentially(String requirements, List<PageSection> sections, int index, FluxSink<String> sink) {
        if (index >= sections.size()) {
            return Mono.empty();
        }

        PageSection section = sections.get(index);
        String sectionId = section.getId();

        logger.info("按顺序生成组件 {}/{}: {}", index + 1, sections.size(), sectionId);

        // 发送组件开始事件
        String componentStartEvent = "{\"stage\": \"component\", \"sectionId\": \"" + sectionId + "\", \"status\": \"start\", \"message\": \"开始生成组件: " + sectionId + "\"}";
        sink.next(componentStartEvent);

        String prompt = CodeGenerationUtil.buildSingleComponentPrompt(
            requirements, section, pageStyle, useGlobalContext, skeletonCode, generatedComponents);

        String systemPrompt = String.format("现在你正在生成'%s'组件，请作为一个专业的前端组件开发者，创建美观、功能完善的HTML、CSS和JavaScript组件。请直接返回代码，不要包含任何标记或解释。", sectionId);

        List<Map<String, String>> messages = LlmUtil.prepareMessages(
            conversationHistory, useGlobalContext, systemPrompt, prompt);

        final StringBuilder componentContent = new StringBuilder();

        return LlmUtil.callLLM(messages, chunk -> {
                // 将响应累积到组件内容和阶段内容中
                componentContent.append(chunk);

                if (!stageContentMap.containsKey("component_" + sectionId)) {
                    stageContentMap.put("component_" + sectionId, new StringBuilder());
                }
                stageContentMap.get("component_" + sectionId).append(chunk);

                // 发送进度事件
                try {
                    String eventData = String.format("{\"stage\": \"component\", \"sectionId\": \"%s\", \"status\": \"progress\", \"content\": %s}",
                        sectionId, objectMapper.writeValueAsString(chunk));
                    sink.next(eventData);
                } catch (Exception e) {
                    logger.error("发送进度事件出错: {}", e.getMessage(), e);
                }
            })
        .then(Mono.fromRunnable(() -> {
            try {
                // 获取组件内容并保存
                String content = componentContent.toString();
                generatedComponents.put(sectionId, content);

                // 保存助手响应到历史
                if (useGlobalContext) {
                    conversationHistory.add(new Message("assistant", content));
                }

                // 集成该组件到骨架中
                String integratedCode = HtmlGenerationUtil.integrateComponentIntoSkeleton(sectionId, content, skeletonCode);
                skeletonCode = new StringBuilder(integratedCode);

                logger.info("组件 {} 集成完毕", sectionId);

                // 发送组件更新事件
                try {
                    String completeContent = skeletonCode.toString();
                    String eventJson = String.format("{\"stage\": \"area_update\", \"status\": \"complete\", \"areaName\": \"%s\", \"completeContent\": %s}",
                        sectionId, objectMapper.writeValueAsString(completeContent));
                    logger.info("发送组件更新事件: {}", eventJson);
                    sink.next(eventJson);
                } catch (Exception e) {
                    logger.error("发送组件更新事件出错: {}", e.getMessage(), e);
                }
            } catch (Exception e) {
                logger.error("处理组件生成结果时出错: {}", e.getMessage(), e);
            }
        }))
        .then(processLevelSectionsSequentially(requirements, sections, index + 1, sink));
    }

    /**
     * 完成生成流程
     *
     * @param sink 事件接收器
     */
    private void finishGeneration(FluxSink<String> sink) {
        // 发送完成事件
        String finalEvent = "{\"stage\": \"all_complete\", \"status\": \"complete\", \"message\": \"代码生成完成\"}";
        logger.info("发送最终完成事件: {}", finalEvent);
        sink.next(finalEvent);
    }

    /**
     * 创建步骤完成事件
     *
     * @param step 步骤
     * @param message 消息
     * @param sourceStage 源阶段
     * @return 事件JSON
     */
    private String createStepCompleteEvent(String step, String message, String sourceStage) {
        try {
            logger.info("创建步骤完成事件: step={}, message={}, sourceStage={}", step, message, sourceStage);
            String completeContent = "";

            // 从源阶段获取累积内容
            StringBuilder accumulatedContent = stageContentMap.get(sourceStage);

            if (accumulatedContent != null && accumulatedContent.length() > 0) {
                // 根据不同阶段处理内容
                if ("skeleton_complete".equals(step)) {
                    completeContent = skeletonCode.toString();
                    logger.info("骨架完成，内容长度: {}", completeContent.length());
                } else if ("components_complete".equals(step)) {
                    completeContent = skeletonCode.toString();
                    logger.info("组件完成，整合内容长度: {}", completeContent.length());
                } else if ("analysis_complete".equals(step)) {
                    completeContent = accumulatedContent.toString();
                    logger.info("分析完成，内容长度: {}", completeContent.length());
                } else {
                    completeContent = accumulatedContent.toString();
                    logger.info("{}阶段完成，内容长度: {}", step, completeContent.length());
                }
            } else {
                logger.warn("{}阶段内容为空", sourceStage);
                // 如果找不到累积内容，填充一些默认内容
                if ("analysis_complete".equals(step)) {
                    completeContent = "需求分析已完成，但未能生成详细内容。";
                } else if ("skeleton_complete".equals(step)) {
                    completeContent = "<!DOCTYPE html>\n<html>\n<head>\n  <title>Generated Page</title>\n</head>\n<body>\n  <h1>Hello World</h1>\n</body>\n</html>";
                } else if ("components_complete".equals(step)) {
                    completeContent = "组件生成完成，但未能提取组件内容。";
                } else {
                    completeContent = "步骤" + step + "已完成，但未能生成内容。";
                }
                logger.info("为空内容生成默认替代内容，长度: {}", completeContent.length());
            }

            String eventJson = String.format("{\"stage\": \"%s\", \"status\": \"complete\", \"message\": \"%s\", \"completeContent\": %s}",
                step, message, objectMapper.writeValueAsString(completeContent));

            logger.info("发送步骤完成事件: {}", eventJson);
            return eventJson;
        } catch (Exception e) {
            logger.error("生成步骤完成事件出错: {}", e.getMessage(), e);
            return "{\"error\": \"生成步骤完成事件出错\"}";
        }
    }

    /**
     * 更新页面风格
     *
     * @param styleRequest 风格请求
     */
    private void updatePageStyle(PageStyleRequest styleRequest) {
        try {
            if (styleRequest.getColorScheme() != null) {
                // 使用反射设置字段值
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("colorScheme");
                field.setAccessible(true);
                field.set(pageStyle, styleRequest.getColorScheme());
            }

            if (styleRequest.getLayoutStyle() != null) {
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("layoutStyle");
                field.setAccessible(true);
                field.set(pageStyle, styleRequest.getLayoutStyle());
            }

            if (styleRequest.getUiFramework() != null) {
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("uiFramework");
                field.setAccessible(true);
                field.set(pageStyle, styleRequest.getUiFramework());
            }

            if (styleRequest.getFontFamily() != null) {
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("fontFamily");
                field.setAccessible(true);
                field.set(pageStyle, styleRequest.getFontFamily());
            }

            if (styleRequest.getDescription() != null) {
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("description");
                field.setAccessible(true);
                field.set(pageStyle, styleRequest.getDescription());
            }

            if (styleRequest.getColorVariables() != null && !styleRequest.getColorVariables().isEmpty()) {
                java.lang.reflect.Field field = pageStyle.getClass().getDeclaredField("colorVariables");
                field.setAccessible(true);
                @SuppressWarnings("unchecked")
                Map<String, String> colorVars = (Map<String, String>) field.get(pageStyle);
                if (colorVars != null) {
                    colorVars.putAll(styleRequest.getColorVariables());
                }
            }
        } catch (Exception e) {
            logger.error("更新页面风格时出错: {}", e.getMessage(), e);
        }
    }

    /**
     * Vue代码生成流程 - 与HTML路径保持相同的事件流
     *
     * @param requirements 需求
     * @return 事件流
     */
    private Flux<String> generateVueCodeInSteps(String requirements) {
        logger.info("开始生成Vue代码步骤，需求长度: {}", requirements.length());

        // 使用纯响应式方式处理流
        return Flux.create(sink -> {
            this.eventSink = sink;  // 保存全局引用，以便其他方法可以使用

            try {
                // 步骤0: 风格设定
                logger.info("开始执行步骤0: 页面风格设定");

                // 发送步骤开始事件
                String styleStartEvent = "{\"stage\": \"style\", \"status\": \"start\", \"message\": \"开始设定页面风格\"}";
                logger.info("发送风格设定开始事件: {}", styleStartEvent);
                sink.next(styleStartEvent);

                // 使用当前的页面风格设置
                String styleCompleteEvent = createStepCompleteEvent("style_complete", "页面风格设定完成", "style");
                Map<String, Object> styleJsonObject;
                try {
                    styleJsonObject = objectMapper.readValue(styleCompleteEvent, Map.class);
                    styleJsonObject.put("styleInfo", pageStyle);
                    String styleJsonStr = objectMapper.writeValueAsString(styleJsonObject);
                    logger.info("发送风格设定完成事件: {}", styleJsonStr);
                    sink.next(styleJsonStr);
                } catch (Exception e) {
                    logger.error("创建风格完成事件失败: {}", e.getMessage(), e);
                }

                // 步骤1: 分析需求及页面结构 - 对Vue和HTML可以使用相同的分析
                logger.info("开始执行步骤1: 分析需求及页面结构");

                // 发送步骤开始事件
                String analysisStartEvent = "{\"stage\": \"analysis\", \"status\": \"start\", \"message\": \"开始分析需求\"}";
                logger.info("发送分析开始事件: {}", analysisStartEvent);
                sink.next(analysisStartEvent);

                // 调用LLM分析需求 - 使用非阻塞方式
                String prompt = CodeGenerationUtil.buildVueAnalysisPrompt(requirements);
                String systemPrompt = "现在你正在执行分析阶段，请作为一个专业的前端开发分析师，分析用户需求并设计页面结构。请使用<!-- SECTION>标签格式返回页面结构。";

                List<Map<String, String>> messages = LlmUtil.prepareMessages(
                    conversationHistory, useGlobalContext, systemPrompt, prompt);

                LlmUtil.callLLM(messages, chunk -> {
                    // 将响应保存到阶段内容中
                    if (!stageContentMap.containsKey("analysis")) {
                        stageContentMap.put("analysis", new StringBuilder());
                    }
                    stageContentMap.get("analysis").append(chunk);

                    // 发送进度事件
                    try {
                        String eventData = String.format("{\"stage\": \"%s\", \"status\": \"progress\", \"content\": %s}",
                            "analysis", objectMapper.writeValueAsString(chunk));
                        sink.next(eventData);
                    } catch (Exception e) {
                        logger.error("发送进度事件出错: {}", e.getMessage(), e);
                    }
                })
                .doOnSuccess(v -> {
                    try {
                        logger.info("分析需求完成，解析页面结构");
                        if (stageContentMap.containsKey("analysis")) {
                            String analysisContent = stageContentMap.get("analysis").toString();
                            CodeGenerationUtil.parsePageStructure(analysisContent, pageSections);

                            // 保存助手响应到历史
                            if (useGlobalContext) {
                                conversationHistory.add(new Message("assistant", analysisContent));
                            }
                        } else {
                            logger.error("未找到analysis阶段的内容");
                        }

                        List<String> ids = pageSections.stream()
                            .map(PageSection::getId)
                            .collect(Collectors.toList());

                        // 发送步骤完成事件
                        String analysisCompleteEvent = createStepCompleteEvent("analysis_complete", "需求分析完成", "analysis");
                        Map<String, Object> analysisJsonObject = objectMapper.readValue(analysisCompleteEvent, Map.class);
                        analysisJsonObject.put("steps", ids);
                        String analysisJsonStr = objectMapper.writeValueAsString(analysisJsonObject);
                        logger.info("发送分析完成事件: {}", analysisJsonStr);
                        sink.next(analysisJsonStr);

                        // 步骤2: 生成Vue页面骨架
                        startVueSkeletonGeneration(requirements, sink);
                    } catch (Exception e) {
                        logger.error("处理分析结果时出错: {}", e.getMessage(), e);
                        sink.error(e);
                    }
                })
                .subscribe(
                    null,
                    error -> {
                        logger.error("分析需求过程中出错: {}", error.getMessage(), error);
                        sink.error(error);
                    }
                );
            } catch (Exception e) {
                logger.error("启动生成流程时出错: {}", e.getMessage(), e);
                sink.error(e);
            }
        });
    }

    /**
     * 启动Vue骨架生成步骤
     *
     * @param requirements 需求
     * @param sink 事件接收器
     */
    private void startVueSkeletonGeneration(String requirements, FluxSink<String> sink) {
        logger.info("步骤1完成，开始执行步骤2: 生成Vue页面骨架");

        // 发送步骤开始事件
        String skeletonStartEvent = "{\"stage\": \"skeleton\", \"status\": \"start\", \"message\": \"开始生成Vue页面骨架\"}";
        logger.info("发送骨架开始事件: {}", skeletonStartEvent);
        sink.next(skeletonStartEvent);

        try {
            // 使用Vue模板生成骨架代码
            String generatedSkeleton = VueGenerationUtil.generateVueSkeletonFromTemplate(
                requirements, pageSections, pageStyle,
                stageContentMap.containsKey("analysis") ? stageContentMap.get("analysis") : null);

            // 保存骨架代码
            skeletonCode = new StringBuilder(generatedSkeleton);
            logger.info("Vue页面骨架生成完成，骨架代码长度: {}", skeletonCode.length());

            // 将骨架代码保存到阶段内容中
            stageContentMap.put("skeleton", skeletonCode);

            // 发送步骤完成事件
            String skeletonCompleteEvent = createStepCompleteEvent("skeleton_complete", "Vue页面骨架生成完成", "skeleton");
            logger.info("发送骨架完成事件: {}", skeletonCompleteEvent);
            sink.next(skeletonCompleteEvent);

            // 步骤3: 生成Vue组件
            startVueComponentsGeneration(requirements, sink);
        } catch (Exception e) {
            logger.error("生成Vue骨架时出错: {}", e.getMessage(), e);
            sink.error(e);
        }
    }

    /**
     * 启动Vue组件生成步骤
     *
     * @param requirements 需求
     * @param sink 事件接收器
     */
    private void startVueComponentsGeneration(String requirements, FluxSink<String> sink) {
        logger.info("步骤2完成，开始执行步骤3: 生成Vue组件");

        // 发送步骤开始事件
        String componentsStartEvent = "{\"stage\": \"components\", \"status\": \"start\", \"message\": \"开始生成Vue组件\"}";
        logger.info("发送组件开始事件: {}", componentsStartEvent);
        sink.next(componentsStartEvent);

        if (!pageSections.isEmpty()) {
            // 如果解析出了页面结构，按层级生成组件
            generateVueComponentsHierarchically(requirements, sink)
                .doOnSuccess(v -> {
                    finishVueGeneration(sink);
                })
                .subscribe(
                    null,
                    error -> {
                        logger.error("生成Vue组件过程中出错: {}", error.getMessage(), error);
                        sink.error(error);
                    }
                );
        } else {
            // 没有解析出页面结构，直接完成
            finishVueGeneration(sink);
        }
    }

    /**
     * 按层级生成Vue组件
     *
     * @param requirements 需求
     * @param sink 事件接收器
     * @return 完成信号
     */
    private Mono<Void> generateVueComponentsHierarchically(String requirements, FluxSink<String> sink) {
        logger.info("开始按层级生成Vue组件");

        // 按层级生成组件
        return generateVueComponentsByLevel(requirements, pageSections, 0, sink)
            .doOnSuccess(v -> {
                // 所有组件生成完毕，发送组件完成事件
                String componentsCompleteEvent = createStepCompleteEvent("components_complete", "Vue组件生成完成", "components");
                logger.info("发送组件完成事件: {}", componentsCompleteEvent);
//                sink.next(componentsCompleteEvent);
            });
    }

    /**
     * 按层级生成Vue组件
     *
     * @param requirements 需求
     * @param sections 页面部分列表
     * @param level 层级
     * @param sink 事件接收器
     * @return 完成信号
     */
    private Mono<Void> generateVueComponentsByLevel(String requirements, List<PageSection> sections, int level, FluxSink<String> sink) {
        // 根据当前级别过滤出要处理的节点
        List<PageSection> currentLevelSections = new ArrayList<>();
        Map<String, List<PageSection>> childrenMap = new HashMap<>();

        // 收集当前层级的节点和子节点
        collectLevelSections(sections, level, 0, currentLevelSections, childrenMap);

        if (currentLevelSections.isEmpty()) {
            return Mono.empty();
        }

        logger.info("开始生成第 {} 层Vue组件，共 {} 个", level+1, currentLevelSections.size());

        // 顺序处理当前层级的所有节点 - 使用严格顺序执行，确保一个组件完全生成后再生成下一个
        return processVueLevelSectionsSequentially(requirements, currentLevelSections, 0, sink)
            .then(Mono.fromRunnable(() -> {
                // 处理下一层级的组件
                List<PageSection> allNextLevelSections = new ArrayList<>();

                // 收集所有子节点
                for (PageSection section : currentLevelSections) {
                    List<PageSection> children = section.getChildren();
                    if (children != null && !children.isEmpty()) {
                        allNextLevelSections.addAll(children);
                    }
                }

                // 如果有子节点，递归处理下一层
                if (!allNextLevelSections.isEmpty()) {
                    logger.info("第 {} 层组件生成完毕，开始生成第 {} 层", level+1, level+2);
                    generateVueComponentsByLevel(requirements, allNextLevelSections, 0, sink)
                        .subscribe();
                }
            }));
    }

    /**
     * 按顺序处理Vue层级节点
     *
     * @param requirements 需求
     * @param sections 页面部分列表
     * @param index 当前索引
     * @param sink 事件接收器
     * @return 完成信号
     */
        private Mono<Void> processVueLevelSectionsSequentially(String requirements, List<PageSection> sections, int index, FluxSink<String> sink) {
        if (index >= sections.size()) {
            return Mono.empty();
        }

        PageSection section = sections.get(index);
        String sectionId = section.getId();

        logger.info("按顺序生成Vue组件 {}/{}: {}", index + 1, sections.size(), sectionId);

        // 发送组件开始事件
        String componentStartEvent = "{\"stage\": \"component\", \"sectionId\": \"" + sectionId + "\", \"status\": \"start\", \"message\": \"开始生成Vue组件: " + sectionId + "\"}";
        sink.next(componentStartEvent);

        // 提取骨架中的已有脚本部分，用于避免重复导入
        String existingImportsStr = extractExistingImports();

        // 使用buildVueComponentPrompt创建提示词
        String promptStr = createEnhancedPrompt(requirements, section, existingImportsStr, sectionId);

        String systemPromptStr = String.format("现在你正在生成'%s'组件，请作为一个专业的Vue前端组件开发者，创建美观、功能完善的Vue 3单文件组件。" +
            "请参考提供的页面骨架上下文，确保代码能与现有骨架无缝集成。请直接返回代码，不要包含任何标记或解释。", sectionId);

        List<Map<String, String>> messages = LlmUtil.prepareMessages(
            conversationHistory, useGlobalContext, systemPromptStr, promptStr);

        final StringBuilder componentContent = new StringBuilder();
        final String existingImports = existingImportsStr; // 创建一个final副本用于lambda

        // 打印提示词到控制台，方便调试
        logger.info("发送给大模型的提示词 - 系统提示词: {}", systemPromptStr);
        logger.info("发送给大模型的提示词 - 用户提示词: {}", promptStr);

        // 如果提示词包含询问模型身份的关键词，添加特定回答
        if (promptStr.toLowerCase().contains("你是谁") ||
            promptStr.toLowerCase().contains("什么模型") ||
            promptStr.toLowerCase().contains("你是什么") ||
            promptStr.toLowerCase().contains("你的名字")) {
            logger.warn("检测到询问模型身份的提示词，将添加特定回答");
            // 在messages中添加一个特定回答
            Map<String, String> specialResponse = new HashMap<>();
            specialResponse.put("role", "assistant");
            specialResponse.put("content", "您好，我是依托claude-4-sonnet-thinking模型的智能助手，在Cursor IDE中为您提供代码编写和问题解答服务，你可以直接告诉我你的需求。");
            messages.add(specialResponse);
        }

        // 先生成当前组件，完成后再生成下一个
        return LlmUtil.callLLM(messages, chunk -> {
            // 将响应累积到组件内容和阶段内容中
            componentContent.append(chunk);

            if (!stageContentMap.containsKey("component_" + sectionId)) {
                stageContentMap.put("component_" + sectionId, new StringBuilder());
            }
            stageContentMap.get("component_" + sectionId).append(chunk);

            // 发送进度事件
            try {
                String eventData = String.format("{\"stage\": \"component\", \"sectionId\": \"%s\", \"status\": \"progress\", \"content\": %s}",
                    sectionId, objectMapper.writeValueAsString(chunk));
                sink.next(eventData);
            } catch (Exception e) {
                logger.error("发送进度事件出错: {}", e.getMessage(), e);
            }
        })
        .then(Mono.fromRunnable(() -> {
            try {
                // 获取组件内容并保存
                String content = componentContent.toString();

                // 如果内容为空或过短，生成一个简单的Vue组件
                if (content == null || content.trim().length() < 50) {
                    logger.warn("组件 {} 内容为空或过短，使用默认组件", sectionId);
                    content = generateDefaultVueComponent(section);
                }

                // 检查和移除可能的重复导入
                String processedContent = removeRedundantImports(content, existingImports);

                generatedComponents.put(sectionId, processedContent);

                // 保存助手响应到历史
                if (useGlobalContext) {
                    conversationHistory.add(new Message("assistant", processedContent));
                }

                // 集成该组件到骨架中
                String integratedCode = VueGenerationUtil.integrateComponentIntoVueSkeleton(sectionId, processedContent, skeletonCode);
                skeletonCode = new StringBuilder(integratedCode);

                logger.info("Vue组件 {} 集成完毕，组件内容长度: {}", sectionId, processedContent.length());

                // 发送组件更新事件
                try {
                    String completeContent = skeletonCode.toString();
                    String eventJson = String.format("{\"stage\": \"area_update\", \"status\": \"complete\", \"areaName\": \"%s\", \"completeContent\": %s}",
                        sectionId, objectMapper.writeValueAsString(completeContent));
                    logger.info("发送组件更新事件: {}", eventJson);
                    sink.next(eventJson);
                } catch (Exception e) {
                    logger.error("发送组件更新事件出错: {}", e.getMessage(), e);
                }
            } catch (Exception e) {
                logger.error("处理Vue组件生成结果时出错: {}", e.getMessage(), e);
            }
        }))
        .then(processVueLevelSectionsSequentially(requirements, sections, index + 1, sink));
    }

    /**
     * 提取骨架中的已有导入语句
     *
     * @return 提取的导入语句
     */
    private String extractExistingImports() {
        try {
            // 提取骨架中已有的脚本内容
            String skeleton = skeletonCode.toString();
            int scriptStartPos = skeleton.indexOf("<script setup>");
            int scriptEndPos = skeleton.indexOf("</script>");

            if (scriptStartPos >= 0 && scriptEndPos > scriptStartPos) {
                String existingScript = skeleton.substring(scriptStartPos + "<script setup>".length(), scriptEndPos).trim();

                // 提取导入语句
                Pattern importPattern = Pattern.compile("import\\s+.*?from\\s+['\"].*?['\"];", Pattern.DOTALL);
                Matcher importMatcher = importPattern.matcher(existingScript);
                StringBuilder imports = new StringBuilder();

                while (importMatcher.find()) {
                    imports.append(importMatcher.group()).append("\n");
                }

                return imports.toString().trim();
            }
        } catch (Exception e) {
            logger.error("提取骨架脚本时出错: {}", e.getMessage());
        }
        return "";
    }

    /**
     * 创建增强的提示词
     *
     * @param requirements 需求
     * @param section 页面部分
     * @param existingImports 已有导入
     * @param sectionId 部分ID
     * @return 增强的提示词
     */
    private String createEnhancedPrompt(String requirements, PageSection section, String existingImports, String sectionId) {
        try {
            String basePrompt = CodeGenerationUtil.buildVueComponentPrompt(
                requirements, section, pageStyle, useGlobalContext, skeletonCode, generatedComponents);
            return basePrompt;
         } catch (Exception e) {
             logger.error("创建Vue组件提示词出错: {}", e.getMessage(), e);
             // 使用一个简单的提示词作为回退
             return String.format("请为'%s'部分创建一个Vue 3组件，使用Element Plus。要求: %s\n\n" +
                 "重要说明：确保所有变量都已定义，不要使用未定义的变量。页面已导入了Vue的ref, reactive, computed, onMounted等API，" +
                 "以及useRoute和useRouter，你可以直接使用这些函数而无需重复导入。", sectionId, requirements);
         }
     }

    /**
     * 移除生成组件中与现有导入重复的导入语句
     *
     * @param componentContent 组件内容
     * @param existingImports 已存在的导入语句
     * @return 处理后的组件内容
     */
    private String removeRedundantImports(String componentContent, String existingImports) {
        if (existingImports.isEmpty() || componentContent.isEmpty()) {
            return componentContent;
        }

        try {
            // 提取组件中的导入语句
            Pattern importPattern = Pattern.compile("import\\s+.*?from\\s+['\"].*?['\"];", Pattern.DOTALL);
            Matcher importMatcher = importPattern.matcher(componentContent);

            // 处理每个导入语句
            while (importMatcher.find()) {
                String importStatement = importMatcher.group();

                // 检查是否与已有导入重复
                if (existingImports.contains(importStatement)) {
                    componentContent = componentContent.replace(importStatement,
                        "// 已在页面中导入: " + importStatement.trim());
                    logger.debug("移除重复导入: {}", importStatement);
                }
            }
        } catch (Exception e) {
            logger.error("移除重复导入时出错: {}", e.getMessage());
        }

        return componentContent;
    }

    /**
     * 生成默认Vue组件
     *
     * @param section 页面部分
     * @return 默认Vue组件代码
     */
    private String generateDefaultVueComponent(PageSection section) {
        String sectionId = section.getId();
        String sectionIdKebab = sectionId.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase();

        return String.format("""
            <template>
              <div class="section-%s">
                <el-row :gutter="20">
                  <el-col :span="24">
                    <el-card shadow="hover">
                      <template #header>
                        <div class="card-header">
                          <h3>%s</h3>
                        </div>
                      </template>
                      <div class="content-placeholder">
                        <p>这里是%s组件的内容区域</p>
                      </div>
                    </el-card>
                  </el-col>
                </el-row>
              </div>
            </template>

            <script setup>
            import { ref, onMounted } from 'vue';

            // 组件状态
            const loading = ref(false);

            // 生命周期钩子
            onMounted(() => {
              console.log('%s 组件已挂载');
            });
            </script>

            <style scoped>
            .section-%s {
              padding: 16px 0;
            }

            .card-header {
              display: flex;
              justify-content: space-between;
              align-items: center;
            }

            .content-placeholder {
              min-height: 100px;
              display: flex;
              align-items: center;
              justify-content: center;
            }
            </style>
            """,
            sectionIdKebab, sectionId, sectionId, sectionId, sectionIdKebab);
    }

    /**
     * 完成Vue代码生成
     *
     * @param sink 事件接收器
     */
    private void finishVueGeneration(FluxSink<String> sink) {
        try {
            logger.info("完成Vue代码生成");

            String allCompleteEvent = "{\"stage\": \"all_complete\", \"status\": \"complete\", " +
                    "\"message\": \"Vue代码生成完成\", " +
                    "\"areaNames\": " + objectMapper.writeValueAsString(generatedComponents.keySet()) + ", " +
                    "\"completeContent\": " + objectMapper.writeValueAsString(skeletonCode.toString()) + "}";

            logger.info("发送全部完成事件");
            sink.next(allCompleteEvent);

        } catch (Exception e) {
            logger.error("完成生成时出错: {}", e.getMessage(), e);
            sink.error(e);
        }
    }
}
